package cn.wizzer.app.web.commons.ext.websocket;

import cn.wizzer.app.bus.modules.services.*;
import cn.wizzer.app.sys.modules.models.Sys_msg;
import cn.wizzer.app.sys.modules.models.Sys_msg_user;
import cn.wizzer.app.sys.modules.models.Sys_user;
import cn.wizzer.app.sys.modules.services.SysMsgService;
import cn.wizzer.app.sys.modules.services.SysMsgUserService;
import cn.wizzer.app.sys.modules.services.SysUserService;
import cn.wizzer.app.web.commons.utils.DateUtil;
import cn.wizzer.app.web.commons.utils.StringUtil;
import org.nutz.aop.interceptor.async.Async;
import org.nutz.dao.Cnd;
import org.nutz.integration.jedis.RedisService;
import org.nutz.integration.jedis.pubsub.PubSubService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Created by wizzer on 2018/6/28.
 */
@IocBean
public class WkNotifyService {
    private static final Log log = Logs.get();
    @Inject
    private PubSubService pubSubService;
    @Inject
    private SysMsgService sysMsgService;
    @Inject
    private SysUserService sysUserService;
    @Inject
    private SysMsgUserService sysMsgUserService;
    @Inject
    private YJbxxLzxxService yjbxxlzxxservice;
    @Inject
    private YJbxxLcxxService yjbxxlcxxservice;
    @Inject
    private RedisService redisService;
    @Inject
    BusEquipmentCheckService busEquipmentCheckService;
    @Inject
    BusEquipmentInspectionService busEquipmentInspectionService;
    @Inject
    BusEquipmentPortableService busEquipmentPortableService;
    @Inject
    BusEquipmentServicingService busEquipmentServicingService;
    @Inject
    BusEquipmentStatusService busEquipmentStatusService;
    @Inject
    BusEquipmentScrapService busEquipmentScrapService;
    @Inject
    BusEquipmentReportService busEquipmentReportService;

    public static NutMap typeMap = NutMap.NEW().addv("0", "通知公告").addv("1", "规章制度")
            .addv("2", "设备资料").addv("3", "知识资料")
            .addv("system", "公共消息").addv("user", "私人消息").addv("bus","待办事项");

    @Async
    public void notify(Sys_msg innerMsg, String rooms[]) {
        String url = "/platform/sys/msg/user/all";
        if (Strings.isNotBlank(innerMsg.getUrl())) {
            url = innerMsg.getUrl();
        }
        NutMap map = new NutMap();
        map.put("action", "notify");
        map.put("title", "您有新的消息");
        map.put("body", innerMsg.getTitle());
        map.put("url", url);
        String msg = Json.toJson(map, JsonFormat.compact());
        if ("system".equals(innerMsg.getType())) {//系统消息发送给所有在线用户
            Set<String> keys = redisService.keys("wsroom:*");
            for (String room : keys) {
                pubSubService.fire(room, msg);
            }
        } else if ("user".equals(innerMsg.getType())) {//用户消息发送给指定在线用户
            for (String room : rooms) {
                Set<String> keys = redisService.keys("wsroom:" + room + ":*");
                for (String key : keys) {
                    pubSubService.fire(key, msg);
                }
            }
        }
    }

    @Async
    public void innerMsg(String room, int size, List<NutMap> list) {
        NutMap map = new NutMap();
        map.put("action", "innerMsg");
        map.put("size", size);//未读消息数
        map.put("list", list);//最新3条消息列表  type--系统消息/用户消息  title--标题  time--时间戳
        String msg = Json.toJson(map, JsonFormat.compact());
        log.debug("msg::::" + msg);
        Set<String> keys = redisService.keys("wsroom:" + room + ":*");
        for (String key : keys) {
            pubSubService.fire(key, msg);
        }
    }


    @Async
    public void getMsg(String loginname) {
        try {
            Sys_user user = sysUserService.getUser(loginname);
            List<NutMap> mapList = new ArrayList<>();
            int transferredCount = yjbxxlzxxservice.getTransferredCount(loginname);//待移交数量
            if(transferredCount>0){
                String url = "/platform/bus/ypxx/transfer";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【样品移交】待移交样品,<span style='color:red'>"+transferredCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            int toReceivedCount = yjbxxlzxxservice.getToReceivedCount(loginname);
            if(toReceivedCount>0){
                String url = "/platform/bus/ypxx/transfer";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【样品移交】待接收样品,<span style='color:red'>"+toReceivedCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            int adReceivedCount = yjbxxlzxxservice.getAdReceivedCount(loginname);
            if(adReceivedCount>0){
                String url = "/platform/bus/ypxx/transfer";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【样品移交】已接收，待处置样品,<span style='color:red'>"+adReceivedCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            int  taskCount = yjbxxlcxxservice.getTaskCount(loginname);
            if(taskCount>0){
                String url = "/platform/bus/rwgl/rwfp";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【任务分配】待分配任务,<span style='color:red'>"+taskCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            int  workCount = yjbxxlcxxservice.getWorkCount(loginname);
            if(workCount>0){
                String url = "/platform/bus/bggl/bz";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【报告编制】待编制报告,<span style='color:red'>"+workCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            int  examineCount = yjbxxlcxxservice.getExamineCount(loginname);
            if(examineCount>0){
                String url = "/platform/bus/bggl/sh";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【报告审核】待审核报告,<span style='color:red'>"+examineCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            int  approveCount = yjbxxlcxxservice.getApproveCount(loginname);
            if(approveCount>0){
                String url = "/platform/bus/bggl/pz";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【报告批准】待批准报告,<span style='color:red'>"+approveCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            int  printCount = yjbxxlcxxservice.getPrintCount(loginname);
            if(printCount>0){
                String url = "/platform/bus/bggl/dy";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【报告打印】待打印报告,<span style='color:red'>"+printCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            int allSize = transferredCount+toReceivedCount+adReceivedCount+taskCount+workCount+examineCount+approveCount+printCount;
            //设备消息

            int servicingDepartmentCount=busEquipmentServicingService.getAuditCount(user);
            if(servicingDepartmentCount>0){
                String url = "/platform/bus/equipment/servicing/audit";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【设备维修】待审核,<span style='color:red'>"+servicingDepartmentCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }

            int servicingCompleteCount=busEquipmentServicingService.getCompleteCount(user);
            if(servicingCompleteCount>0){
                String url = "/platform/bus/equipment/servicing/complete";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【设备维修】待维修完成,<span style='color:red'>"+servicingCompleteCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            allSize+=servicingDepartmentCount+servicingCompleteCount;

            //
            int statusDepartmentCount=busEquipmentStatusService.getAuditCount(user);
            if(statusDepartmentCount>0){
                String url = "/platform/bus/equipment/status/audit";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【设备启用/停用】待审核,<span style='color:red'>"+statusDepartmentCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }

            allSize+=statusDepartmentCount;

//
            int scrapDepartmentCount=busEquipmentScrapService.getAuditCount(user);
            if(scrapDepartmentCount>0){
                String url = "/platform/bus/equipment/scrap/audit";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【设备报废】待审核,<span style='color:red'>"+scrapDepartmentCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            allSize+=scrapDepartmentCount;

            int reportDepartmentCount=busEquipmentReportService.getAuditCount(user);
            if(reportDepartmentCount>0){
                String url = "/platform/bus/equipment/report/audit";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【设备确认】待审核,<span style='color:red'>"+reportDepartmentCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            allSize+=reportDepartmentCount;


            int portableDepartmentCount=busEquipmentPortableService.getAuditCount(user);//外携
            if(portableDepartmentCount>0){
                String url = "/platform/bus/equipment/portable/audit";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【设备借出】待审核,<span style='color:red'>"+portableDepartmentCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            int portableCompleteCount=busEquipmentPortableService.getCompleteCount(user);//外携
            if(portableCompleteCount>0){
                String url = "/platform/bus/equipment/portable/complete";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【设备借出】待设备返回,<span style='color:red'>"+portableCompleteCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            allSize+=portableDepartmentCount+portableCompleteCount;

            int checkDepartmentCount=busEquipmentCheckService.getCheckAuditCount(user);
            if(checkDepartmentCount>0){
                String url = "/platform/bus/equipment/check/audit";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【设备维护】待审核,<span style='color:red'>"+checkDepartmentCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            allSize+=checkDepartmentCount;


            /*int inspectionCompleteCount=busEquipmentInspectionService.getCompleteCount(user);//送检
            if(inspectionCompleteCount>0){
                String url = "/platform/bus/equipment/inspection/complete";
                mapList.add(NutMap.NEW().addv("type", typeMap.get("bus"))
                        .addv("title", "【设备送检】待送回,<span style='color:red'>"+inspectionCompleteCount+"</span>条，请及时处置！")
                        .addv("url", url)
                        .addv("time", DateUtil.getDate()));
            }
            allSize+=inspectionCompleteCount;*/



            //通过用户名查询未读消息
            int size = sysMsgUserService.getUnreadNum(loginname);

            List<Sys_msg_user> list = sysMsgUserService.getUnreadList(loginname, 1, 5);
            for (Sys_msg_user msgUser : list) {
                String url = "/platform/sys/msg/user/all/detail/" + msgUser.getMsgId();
                if (Strings.isNotBlank(msgUser.getMsg().getUrl())) {
                    url = msgUser.getMsg().getUrl();
                }
                mapList.add(NutMap.NEW().addv("msgId", msgUser.getMsgId()).addv("type", typeMap.getString(msgUser.getMsg().getMsgType()))
                        .addv("title", msgUser.getMsg().getTitle())
                        .addv("url", url)
                        .addv("time", Times.format("yyyy-MM-dd HH:mm", Times.D(1000 * msgUser.getMsg().getSendAt()))));
            }
            allSize += size;


            innerMsg(loginname,allSize, mapList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Async
    public void offline(String loginname, String httpSessionId) {
        NutMap map = new NutMap();
        map.put("action", "offline");
        map.put("title", "");
        map.put("body", "");
        map.put("url", "");
        String msg = Json.toJson(map, JsonFormat.compact());
        try {
            pubSubService.fire("wsroom:" + loginname + ":" + httpSessionId, msg);
            redisService.expire("wsroom:" + loginname + ":" + httpSessionId, 60 * 3);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Async
    public void offlineNoMsg(String loginname, String httpSessionId) {
        try {
            redisService.expire("wsroom:" + loginname + ":" + httpSessionId, 60 * 3);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

}
